home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / clang / ebksrc.zip / PCLED.CPP < prev    next >
C/C++ Source or Header  |  1991-07-30  |  7KB  |  333 lines

  1. /*
  2.  
  3.     pcled.cpp
  4.     7-30-91
  5.     Line Edit for the IBM PC Text Modes.
  6.  
  7.     Copyright 1991
  8.     John W. Small
  9.     All rights reserved
  10.     Use freely but acknowledge authorship and copyright.
  11.  
  12.  
  13.     PSW / Power SoftWare
  14.     P.O. Box 10072
  15.     McLean, Virginia 22102 8072 USA
  16.  
  17.     Voice: (703) 759-3838
  18.     CIS: 73757,2233
  19.  
  20. */
  21.  
  22.  
  23. #include <ctype.h>
  24. #include <string.h>
  25. #include <conio.h>
  26. #include <pckey.hpp>
  27. #include <pcled.hpp>
  28.  
  29.  
  30.  
  31. Palette LineEdit::defaultP = {
  32.  
  33.     0,   /*  monochrome    or           color   */
  34.  
  35.     svideo(WHITE,BLACK),        svideo(BLACK,LIGHTGRAY),
  36.     svideo(BLACK,LIGHTGRAY),    svideo(BLUE,LIGHTGRAY),
  37.     svideo(DARKGRAY,LIGHTGRAY),    svideo(WHITE,BLUE)
  38. };
  39.  
  40.  
  41. int LineEdit::edit(char *response, int sizeofResponse,
  42.     int flen, int x, int y, const char *pref,
  43.     const char *prompt, TFvaliD validate)
  44. {
  45.     struct text_info ti;
  46.     CursorShape cursor;
  47.     int maxlen, insmode, rlen, i, fscol, c, erase, j;
  48.     int owscroll;
  49.     int w, h;
  50.  
  51.     if ((maxlen = sizeofResponse - 1) < 1 || flen < 1)
  52.         return 0;
  53.     gettextinfo(&ti);
  54.     w = ti.winright - ti.winleft + 1;
  55.     h = ti.winbottom - ti.wintop + 1;
  56.     if (x < 1 || y < 1)  {
  57.         x = wherex();
  58.         y = wherey();
  59.     }
  60.     else if (x + (prompt?strlen(prompt)+2:0)
  61.         >= w - 1 || y > h)
  62.         return 0;
  63.         // two extra spaces required for arrows
  64.  
  65.     cursor.saveOrig();
  66.     owscroll = _wscroll;
  67.     _wscroll = 0;
  68.     mappalette(P);
  69.  
  70.     insmode = 1;
  71.     cursor.normal();
  72.     gotoxy(x,y);
  73.  
  74.     if (prompt)  {
  75.         mapvideo(PROMPT,P);
  76.         cprintf("%s: ",prompt);
  77.     }
  78.     if (pref)  {
  79.         i = strlen(pref);
  80.         strncpy(response,pref,maxlen);
  81.         if (i > maxlen)
  82.             i = maxlen;
  83.     }
  84.     else
  85.         i = 0;
  86.     response[rlen = i] = '\0';   /*  i & fscol are zero biased  */
  87.  
  88.  
  89.     x = wherex(); y = wherey();
  90.  
  91.     /*  leave two extra spaces for backward and forward arrows  */
  92.     if (flen > w-x-1)
  93.         flen = w-x-1;
  94.  
  95.     if (i > flen)
  96.         fscol = i + 1 - flen;
  97.     else
  98.         fscol = 0;
  99.  
  100.     erase = 1;
  101.     mapvideo(RESPONSE,P);
  102.  
  103.     while (1)  {
  104.         cursor.off();
  105.         gotoxy(x,y);
  106.         if (erase)  {
  107.             putch(fscol?'\021':' ');
  108.             mapvideo(PREFERENCE,P);
  109.             j = cprintf("%-.*s",flen,&response[fscol]);
  110.             mapvideo(RESPONSE,P);
  111.             cprintf("%*.s",flen-j,"");
  112.             putch((fscol+flen < rlen)?'\020':' ');
  113.  
  114.         }
  115.         else
  116.             cprintf("%c%-*.*s%c",(fscol?'\021':' '),
  117.                 flen,flen,&response[fscol],
  118.                 ((fscol+flen<rlen)?'\020':' '));
  119.         /*  leave extra space for backward arrow  */
  120.         gotoxy(x+i-fscol+1,y);
  121.         cursor.on();
  122.         c = PCK.getkey();
  123.         switch (c)  {
  124.         case -Home:
  125.             fscol = i = 0;
  126.             break;
  127.         case -EndKey:
  128.             i = rlen;
  129.             if (i >= fscol + flen)
  130.                 fscol = i+1 - flen;
  131.             break;
  132.         case CtrlS:
  133.         case -LArr:
  134.             if (i)
  135.                 if (--i < fscol)
  136.                     fscol = i;
  137.             break;
  138.         case CtrlA:
  139.         case -CtrlLArr:
  140.             while (i && !isalnum(response[i-1])) i--;
  141.             while (i && isalnum(response[i-1])) i--;
  142.             if (i < fscol)
  143.                 fscol = i;
  144.             break;
  145.         case CtrlD:
  146.         case -RArr:
  147.             if (i < rlen)
  148.                 if (++i >= fscol + flen)
  149.                     fscol = i+1 - flen;
  150.             break;
  151.         case CtrlF:
  152.         case -CtrlRArr:
  153.             while (i < rlen && isalnum(response[i])) i++;
  154.             while (i < rlen && !isalnum(response[i])) i++;
  155.             if (i >= fscol + flen)
  156.                 fscol = i+1 - flen;
  157.             break;
  158.         case -UpArr:
  159.         case -DnArr:
  160.             if (pref)  {
  161.                 i = strlen(pref);
  162.                 strncpy(response,pref,maxlen);
  163.                 if (i > maxlen)
  164.                     i = maxlen;
  165.                 response[rlen = i] = '\0';
  166.                 /*  i & fscol are zero biased  */
  167.                 if (i > flen)
  168.                     fscol = i + 1 - flen;
  169.                 else
  170.                     fscol = 0;
  171.                 erase = 1;
  172.                 continue;
  173.             }
  174.             break;
  175.         case CtrlV:
  176.         case -InsKey:
  177.             if (insmode)  {
  178.                 cursor.block();
  179.                 insmode = 0;
  180.             }
  181.             else  {
  182.                 cursor.normal();
  183.                 insmode = 1;
  184.             }
  185.             break;
  186.         case -DelKey:
  187.             if (response[i] && rlen)  {
  188.                 strcpy(&response[i],&response[i+1]);
  189.                 rlen--;
  190.             }
  191.             break;
  192.         case CR:
  193.             if (validate)
  194.                 if (!(*validate)(response,maxlen))  {
  195.                     putch('\a');
  196.                     erase = 1;
  197.                     continue;
  198.                 }
  199.             gotoxy(x,y);
  200.             cprintf(" %-*.*s ",flen,flen,response);
  201.             gotoxy(x+1,y);
  202.             _wscroll = owscroll;
  203.             textattr(ti.attribute);
  204.             cursor.restoreOrig();
  205.             return 1;
  206.         case ESC:
  207.             response[i=0] = '\0';
  208.             gotoxy(x,y);
  209.             cprintf(" %-*.*s ",flen,flen,response);
  210.             gotoxy(x+1,y);
  211.             _wscroll = owscroll;
  212.             textattr(ti.attribute);
  213.             cursor.restoreOrig();
  214.             return 0;
  215.         case BACKSP:    /* CtrlH */
  216.             if (i)  {
  217.                 strcpy(&response[i-1],&response[i]);
  218.                 rlen--;
  219.                 if (--i < fscol)
  220.                     fscol = i;
  221.                 else if (fscol)
  222.                     fscol--;
  223.             }
  224.             break;
  225.         case CtrlT:
  226.             if (i == rlen) break;
  227.             if (isalnum(response[i]))
  228.                 while (isalnum(response[i]) && i < rlen)  {
  229.                     strcpy(&response[i],&response[i+1]);
  230.                     rlen--;
  231.                 }
  232.             else if (!isspace(response[i])) {
  233.                 strcpy(&response[i],&response[i+1]);
  234.                 rlen--;
  235.             }
  236.             while (isspace(response[i]) && i < rlen)  {
  237.                 strcpy(&response[i],&response[i+1]);
  238.                 rlen--;
  239.             }
  240.             break;
  241.         case CtrlY:
  242.             response[rlen = fscol = i = 0] = '\0';
  243.             break;
  244.         case CtrlQ:
  245.             cursor.off();
  246.             gotoxy(x,y);
  247.             blinkvideo();
  248.             putch('Q');
  249.             unblinkvideo();
  250.             gotoxy(x+i-fscol+1,y);
  251.             cursor.on();
  252.             switch (PCK.getkey())  {
  253.             case CtrlY:
  254.             case 'Y':
  255.             case 'y':
  256.                 response[rlen = i] = '\0';
  257.                 break;
  258.             case CtrlS:
  259.             case 'S':
  260.             case 's':
  261.                 fscol = i = 0;
  262.                 break;
  263.             case CtrlD:
  264.             case 'D':
  265.             case 'd':
  266.                 i = rlen;
  267.                 if (i >= fscol + flen)
  268.                     fscol = i+1 - flen;
  269.                 break;
  270.             default:
  271.                 putch('\a');
  272.                 break;
  273.             }
  274.             break;
  275.         case TAB:  // tabs not allowed
  276.             putch('\a');
  277.             break;
  278.         default:
  279.             if (isprint(c) && rlen <= maxlen)  {
  280.                 if (erase)  {
  281.                     response[rlen = fscol = i = 0] = '\0';
  282.                     gotoxy(x,y);
  283.                     cprintf(" %-*.*s ",flen,flen,response);
  284.                 }
  285.                 if (insmode || i >= rlen)  {
  286.                     if (rlen == maxlen) {
  287.                         putch('\a');
  288.                         break;
  289.                     }
  290.                     for (j = rlen; j >= i; j--)
  291.                         response[j+1] = response[j];
  292.                     rlen++;
  293.                 }
  294.                 response[i] = c;
  295.                 if (i < rlen)
  296.                     if (++i >= fscol + flen)
  297.                         fscol = i+1 - flen;
  298.             }
  299.             else
  300.                 putch('\a');
  301.             break;
  302.         }
  303.         erase = 0;
  304.     }
  305. }
  306.  
  307. int LineEditWindow::edit(char *response, int sizeofResponse,
  308.     int flen, int x, int y, const char *pref,
  309.     const char *prompt, TFvaliD validate)
  310. {
  311.     struct text_info ti;
  312.  
  313.     if (sizeofResponse < 2 || flen < 1)
  314.         return 0;
  315.     if (flen > sizeofResponse)
  316.         flen = sizeofResponse;
  317.     gettextinfo(&ti);
  318.     if (x < 1 || y < 1 ||
  319.         x + flen + 3 > ti.screenwidth ||
  320.         y + 3 > ti.screenheight)  {
  321.         x = ti.screenwidth/2 - flen/2 - 2;
  322.         y = ti.screenheight/2 - 1;
  323.     }
  324.     if (!window(x,y,x+3+flen,y+2))
  325.         return 0;
  326.     if (prompt)
  327.         putTitle(prompt);
  328.     int ok = LineEdit::edit(response,sizeofResponse,
  329.         flen,1,1,pref,(char *)0,validate);
  330.     close();
  331.     return ok;
  332. }
  333.